package com.landmark;

import java.awt.EventQueue;
import java.io.FileWriter;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import org.htmlparser.Parser;
import org.htmlparser.util.NodeList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class SafarilandCat extends SwingWorker<Boolean, Boolean> {

    FileWriter fw = null;
    FileWriter errorFile = null;
    int pageNo;
    StringBuffer sb = new StringBuffer();
    Hashtable<String, String> htModelLinks = new Hashtable<String, String>();
    Hashtable<String, String> htMainCategories = new Hashtable<String, String>();
    Hashtable<String, String> htSubCategories = new Hashtable<String, String>();
    String status = "";
    JTextArea txtArea;
    UMProgressBar pBar = null;
    int lineCount = 0;

    @Override
    protected Boolean doInBackground() throws Exception {
        start();
        return true;
    }

    @Override
    protected void done() {
        Util.taskCompleteMsg(status);
    }

    public void start() {
        try {
            String dirName = "./outputs";
            String imagesPath = "./outputs/SafarilandImages";
            String barcoSwatchesPath = "./outputs/Safariland";

            Util.createDirectory(dirName);
            Util.createDirectory(imagesPath);
            Util.createDirectory(barcoSwatchesPath);

            txtArea = Util.createOutputFile("Safariland");
            HelperBean helperBean = Util.getHelperBean();

            fw = new FileWriter(helperBean.getOutputFile());
            errorFile = new FileWriter(helperBean.getErrorFile());
            getMainCategories("http://www.safariland.com/SiteMap.aspx");

            Enumeration enume = htMainCategories.keys();
            while (enume.hasMoreElements()) {
                String url = (String) enume.nextElement();
                getSubcategories(url);
            }
            System.out.println(htSubCategories.size());

            Enumeration enumeSub = htSubCategories.keys();
            lineCount = 0;
            pBar = new UMProgressBar();
            Util.getHelperBean().setLineCount(htSubCategories.size());
            while (enumeSub.hasMoreElements()) {
                String url = (String) enumeSub.nextElement();
                Util.getHelperBean().setCurrentCount(lineCount++);
                try {
                    getProductUrls(url);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                EventQueue.invokeLater(pBar);
                if (Util.getHelperBean().getLineCount() == lineCount) {
                    Util.getHelperBean().setProcessingDone(true);
                    pBar.close();
                }
            }
            txtArea.append("\nFiles are located at : \n" + helperBean.getOutputFile().getAbsolutePath() + "\n" + helperBean.getErrorFile().getAbsolutePath() + "\n");
            txtArea.append("Total products : " + htModelLinks.size() + "\n");
            txtArea.paintImmediately(txtArea.getVisibleRect());
            Util.getHelperBean().setLineCount(htModelLinks.size());

            System.out.println("Total products : " + htModelLinks.size());
            iterateCollection(htModelLinks);

            if (fw != null) {
                fw.close();
            }

        } catch (Exception e) {
            status = e.toString();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (Exception e1) {
                // TODO: handle exception
            }
        }
        status = status.trim().equals("") ? "Done processing." : status;
        if (Util.getHelperBean().isTerminateCurrentProcess()) {
            status = "Process Terminated";
        }
        txtArea.append("\n" + status);
    }

    /**
     *
     * @param htLinks
     */
    private void iterateCollection(Hashtable<String, String> htLinks) throws Exception {
        lineCount = 0;
        if (pBar.isActive() || pBar.isShowing()) {
            pBar.close();
        }
        pBar = new UMProgressBar();
        Enumeration<String> keys = htLinks.keys();
        fw.write("productId,productName,ProductDesc, Category\n");
        while (keys.hasMoreElements()) {
            if (Util.getHelperBean().isTerminateCurrentProcess()) {
                break;
            }
            String key = (String) keys.nextElement();
            txtArea.append("Processing page: " + key + "\n");
            txtArea.paintImmediately(txtArea.getVisibleRect());
            sb = new StringBuffer();
            Util.getHelperBean().setCurrentCount(lineCount++);
            try {
                processModels(htLinks.get(key).toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
            fw.write(sb.toString().replaceAll("\n", "").replace("   ", "").replaceAll("<#NEWLINE#>", "\n"));
            fw.write("\n");
            fw.flush();
            EventQueue.invokeLater(pBar);
            if (Util.getHelperBean().getLineCount() == lineCount) {
                Util.getHelperBean().setProcessingDone(true);
                pBar.close();
            }
        }
    }

    /**
     *
     * @param aUrl
     */
    private void processModels(String aUrl) throws Exception {
        try {
            Parser parser = Util.getParserFromUrl(aUrl, null);
            NodeList nl = parser.parse(null);

            String productId = Util.getHelperBean().getInputHTML().select("#greyhdr").select("h1").text();
            String prdtNameLs = Util.getHelperBean().getInputHTML().select("#greyhdr").select("h2").text();

            sb.append(productId + ",");
            sb.append(prdtNameLs + ",");

            Elements prdtDescElements = Util.getHelperBean().getInputHTML().select("#Table2").select("tbody").select("tr");
            String desc = "";
            for (Element ele : prdtDescElements) {
                System.out.println("tage name : " + ele.tagName());
                Elements childEle = ele.select("td");
                for (Element el : childEle) {
                    boolean bo = el.hasAttr("valign");
                    if (el.hasAttr("valign")) {
                        desc += el.html();
                    }
                }
            }
            sb.append(desc.replaceAll(",", "#044;") + ",");

            Elements category = Util.getHelperBean().getInputHTML().select(".ltgreybg").select("a");
            String categoryPath = "";
            for (Element ele : category) {
                categoryPath += ele.text() + ">";
            }
            sb.append(categoryPath);
            sb.append("<#NEWLINE#>");
            
            Elements fitInformationHeader = Util.getHelperBean().getInputHTML().select(".variantheader").select("td");
            String header = "";
            for (Element ele : fitInformationHeader) {
                header += ele.text() + ",";
            }
            sb.append(header);
            sb.append("<#NEWLINE#>");
            
            Elements fitInformationElements = Util.getHelperBean().getInputHTML().select(".variant").select("tbody").select("tr:not(.variantheader)");
            for (Element ele : fitInformationElements) {
                Elements fitSubElements = ele.select("td");
                for (Element el : fitSubElements) {
                    String str = el.text();
                    sb.append(str.replaceAll(",", "#044;") + ",");
                }
                sb.append("<#NEWLINE#>");
            }

        } catch (SocketTimeoutException e) {
            try {
                processModels(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                processModels(aUrl);
            } catch (Exception e1) {
            }
        }
    }

    private void getProductUrls(String aUrl) throws Exception {
        try {
            System.out.println("Product Url : " + aUrl);
            Document doc = Jsoup.connect(aUrl).get();
            Elements elements = doc.select(".small").select("a[href]");
            System.out.println(elements.size());
            for (Element element : elements) {
                String absoluteUrl = element.attr("abs:href");
                if (absoluteUrl.contains("pid=")) {
                    htModelLinks.put(absoluteUrl, absoluteUrl);
                }
            }
        } catch (SocketTimeoutException e) {
            try {
                getProductUrls(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                getProductUrls(aUrl);
            } catch (Exception e1) {
            }
        }
    }

    private void getMainCategories(String aUrl) throws Exception {
        try {
            Document doc = Jsoup.connect(aUrl).get();
            Elements elements = doc.select("div.siteMapRightColumn").select("div.siteMapCategory").select("a[href]");
//            System.out.println(elements.size());
            for (Element element : elements) {
                String absoluteUrl = element.attr("abs:href");
                if (absoluteUrl.contains("DutyGear/")) {
                    htMainCategories.put(absoluteUrl, absoluteUrl);
//                    System.out.println("Main cats url : " +absoluteUrl);
                }
            }
//            System.out.println("Main cats size : " +htMainCategories.size());

        } catch (SocketTimeoutException e) {
            try {
                getMainCategories(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                getMainCategories(aUrl);
            } catch (Exception e1) {
            }
        }
    }

    private void getSubcategories(String aUrl) throws Exception {
        try {
            Document doc = Jsoup.connect(aUrl).get();
            Elements elements = doc.select(".small").select("a[href]");
            for (Element element : elements) {
                String absoluteUrl = element.attr("abs:href");
                htSubCategories.put(absoluteUrl, absoluteUrl);
//                System.out.println("sub cats url : " +absoluteUrl);
            }
        } catch (SocketTimeoutException e) {
            try {
                getSubcategories(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                getSubcategories(aUrl);
            } catch (Exception e1) {
            }
        }
    }
}
